﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using GrafosWindows.Model;

namespace GrafosWindows
{
    public partial class JanelaGrafo : Form
    {
        #region Atributos
        private Grafo _grafo;
        internal Grafo Grafo
        {
            get { return _grafo; }
            set { _grafo = value; }
        }

        private Graphics _graphics;
        public Graphics Graphics
        {
            get { return _graphics; }
            private set { _graphics = value; }
        }

        private Bitmap backBuffer;
        #endregion

        public JanelaGrafo(Grafo grafo)
        {
            InitializeComponent();

            backBuffer = new Bitmap(panelGrafo.Width, panelGrafo.Height);
            Graphics = Graphics.FromImage(backBuffer);
            panelGrafo.Paint += panelGrafo_Paint;

            Show();

            if (grafo != null)
            {
                this.Grafo = grafo;
                PintarGrafoPanel();
            }

        }

        void panelGrafo_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.DrawImageUnscaled(backBuffer, 0, 0);
        }

        public JanelaGrafo() : this(null) { }

        private void PintarGrafoPanel()
        {
            panelGrafo.Controls.Clear();
            Graphics.Clear(Color.White);
            panelGrafo.Invalidate();
            pintarGrafo();
        }

        #region Código do Panel do Grafo
        private void pintarGrafo()
        {
            //No máximo 5 nós por linha
            int qtdeLinhas = 1;
            if (Grafo.Cardinalidade > 5)
            {
                qtdeLinhas = Grafo.Cardinalidade % 5;
                qtdeLinhas++;
            }

            int xInicial = 50;
            int yInicial = 60;

            int tamanho = 15;

            SolidBrush brush = new SolidBrush(Color.DarkGreen);
            SolidBrush brushEffect = new SolidBrush(Color.Black);
            SolidBrush brushText = new SolidBrush(Color.Black);

            for (int j = 0; j < Grafo.ListaVertices.Count; j++)
            {
                //Para garantir que ficará no centro do vértice somamos com tamanho/2
                if (Grafo.ListaVertices[j].Posicao == null)
                {
                    Grafo.ListaVertices[j].Posicao = new Point(xInicial + (tamanho / 2), yInicial + (tamanho / 2));
                }

                Graphics.DrawString(Grafo.ListaVertices[j].Name, new Font("Arial", 12), brushText, (float)xInicial, (float)yInicial - tamanho);
                Graphics.FillEllipse(brushEffect, xInicial - 1, yInicial - 1, tamanho + 2, tamanho + 2);
                Graphics.FillEllipse(brush, xInicial, yInicial, tamanho, tamanho);

                xInicial += 60;
                switch ((j + 1) % 5)
                {
                    case 0: break;
                    case 1: yInicial += (20 + ((j + 1) % 5) * 5); break;
                    case 2: yInicial -= (30 + ((j + 1) % 5) * 5); break;
                    case 3: yInicial -= (10 + ((j + 1) % 5) * 5); break;
                    case 4: yInicial += (15 + ((j + 1) % 5) * 5); break;
                }

                if ((j + 1) % 5 == 0)
                {
                    xInicial = 50 + ((j + 1) % 5) * 5;
                    yInicial += 80;
                }
            }

            brush.Dispose();
            brushText.Dispose();

            Pen pen = new Pen(Color.Red);

            foreach (Aresta aresta in Grafo.ListaArestas)
            {
                pen = new Pen(Color.FromArgb(25 * aresta.Peso, 0, 0));
                Graphics.DrawLine(pen, aresta.V.Posicao, aresta.U.Posicao);
            }

            pen.Dispose();
        }
        #endregion

        private void buttonClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }
}
